home *** CD-ROM | disk | FTP | other *** search
- unit TestSafeCallU;
-
- {$ifdef Ver80} { Delphi 1.0x }
- {$define DelphiLessThan2}
- {$define DelphiLessThan3}
- {$endif}
- {$ifdef Ver90} { Delphi 2.0x }
- {$define DelphiLessThan3}
- {$endif}
- {$ifdef Ver93} { C++ Builder 1.0x }
- {$define DelphiLessThan3}
- {$endif}
- {$ifdef DelphiLessThan3}
- 'Safecall not supported before Delphi 3'
- {$endif}
-
- interface
-
- uses
- comobj,
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, Db, Grids, DBGrids, DBTables;
-
- type
- TForm1 = class(TForm)
- Table1: TTable;
- DBGrid1: TDBGrid;
- DataSource1: TDataSource;
- CheckBox1: TCheckBox;
- Button1: TButton;
- Button2: TButton;
- Button3: TButton;
- Button4: TButton;
- procedure CheckBox1Click(Sender: TObject);
- procedure Button1Click(Sender: TObject);
- procedure Button2Click(Sender: TObject);
- procedure Button3Click(Sender: TObject);
- procedure Button4Click(Sender: TObject);
- private
- procedure DoSomething; safecall;
- public
- function SafeCallException(ExceptObject: TObject;
- ExceptAddr: Pointer): HResult; override;
- end;
-
- var
- Form1: TForm1;
-
- implementation
-
- {$R *.DFM}
-
- uses
- BDE;
-
- var
- EClass: ExceptClass = nil;
- EMsg: String;
-
- procedure SafeCallError(ErrorCode: Integer; ErrorAddr: Pointer);
- begin
- //Must raise exception, but if SafeCallException handled
- //the problem, we'll raise a "silent" exception
- if EClass <> nil then
- raise EClass.Create(EMsg)
- else
- SysUtils.Abort
- end;
-
- procedure LogError(ExceptObject: Exception; ExceptAddr: Pointer);
- var
- Log: TextFile;
- const
- LogName = 'C:\DelphiLog.Txt';
- begin
- AssignFile(Log, LogName);
- if FileExists(LogName) then
- Append(Log)
- else
- Rewrite(Log);
- try
- WriteLn(Log, Format('%s'#9'%s'#9'$%p'#9'%s',
- [ExceptObject.ClassName, ExceptObject.Message,
- ExceptAddr, Application.ExeName]))
- finally
- CloseFile(Log)
- end;
- end;
-
- function TForm1.SafeCallException(ExceptObject: TObject;
- ExceptAddr: Pointer): HResult;
- var
- Handled: Boolean;
- begin
- Result := E_UNEXPECTED;
- Handled := False;
- if ExceptObject is EDBEngineError then
- begin
- Handled := True;
- case EDBEngineError(ExceptObject).Errors[0].ErrorCode of
- DBIERR_DETAILRECORDSEXIST:
- ShowMessage('Delete/change detail records first...');
- DBIERR_KEYVIOL:
- ShowMessage('Already used that one')
- else
- Handled := False
- end
- end;
- LogError(Exception(ExceptObject), ExceptAddr);
- if Handled then
- EClass := nil
- else
- begin
- EClass := ExceptClass(ExceptObject.ClassType);
- EMsg := Exception(ExceptObject).Message
- end
- end;
-
- procedure TForm1.DoSomething;
- begin
- Table1.Next
- end;
-
- procedure TForm1.CheckBox1Click(Sender: TObject);
- begin
- Table1.Active := CheckBox1.Checked
- end;
-
- procedure TForm1.Button1Click(Sender: TObject);
- begin
- DoSomething
- end;
-
- procedure TForm1.Button2Click(Sender: TObject);
- begin
- CheckBox1.Checked := False;
- DoSomething
- end;
-
- procedure TForm1.Button3Click(Sender: TObject);
- begin
- Table1.Cancel;
- Table1.First;
- Table1.Edit;
- Table1.FieldByName('CustNo').AsInteger := 1231;
- DoSomething
- end;
-
- procedure TForm1.Button4Click(Sender: TObject);
- begin
- Table1.Cancel;
- Table1.Insert;
- Table1.FieldByName('CustNo').AsInteger := 1221;
- DoSomething
- end;
-
- initialization
- SafeCallErrorProc := @SafeCallError;
- finalization
- SafeCallErrorProc := nil;
- end.
-